package model

import java.util.LinkedList
import model.*
import util.*

abstract class Deck() {
    val cards: MutableList<Card> = LinkedList<Card>()

    fun cardVictory(card: Card) = when(card) {
        gardens -> cards.size() / 10
        is VictoryCard -> card.victoryPoints
        else -> 0
    }
    fun victoryPoints() = cards.fold(0, { sum, card -> sum + cardVictory(card) })

    fun shuffle() {
        val copy = cards.shuffledCopy()
        cards.clear()
        cards.addAll(copy)
    }
    fun push(card: Card?) = cards.safeAdd(card)
    fun pop() = if (cards.size() == 0) null else cards.remove(cards.size() - 1)
    fun size() = cards.size()
    fun clear() = cards.clear()
    fun forEach(fn: (Card) -> Unit) = cards.forEach(fn)

    class object {
        fun startDeck(): Deck {
            val result = ClosedDeck()
            result.push(gold)
            result.push(cooper)
            result.push(village)
            result.push(village)
            result.push(village)
            result.push(cellar)
            result.push(cellar)

            //3 times { result.push(estate) }
            //7 times { result.push(cooper) }
            //result.shuffle()
            return result
        }
        fun openDeck(size: Int, init: (Int) -> Card): OpenDeck {
            val result = OpenDeck()
            for (i in 1..size) result.push(init.invoke(i - 1))
            return result
        }
    }

}

class ClosedDeck: Deck()

class OpenDeck: Deck() {
    fun peek() = if (cards.size > 0) cards[cards.size() - 1] else null
}

